#include <SFML/Graphics/RenderTarget.hpp>
#include <nice2d/util.h>
#include <nice2d/string.h>
#include <nice2d/spritetextdecorator.h>

IMPLEMENT_OBJECT(SpriteTextDecorator, SpriteDecorator)

class SpriteTextDecoratorData
{
public:
    TextOption option;
    sf::Text text;
};

SpriteTextDecorator::SpriteTextDecorator(const TextOption &option):
    data(new SpriteTextDecoratorData())
{
    data->option = option;
    TextOption::apply(data->text, option);
}

SpriteTextDecorator::~SpriteTextDecorator()
{
}

void SpriteTextDecorator::setText(const sf::String &text)
{
    data->text.setString(text);
    update();
}

sf::String SpriteTextDecorator::getText() const
{
    return data->text.getString();
}

void SpriteTextDecorator::setTextColor(const sf::Color &color)
{
    data->text.setFillColor(color);
}

sf::Color SpriteTextDecorator::getTextColor() const
{
    return data->text.getFillColor();
}

void SpriteTextDecorator::updateAnchor()
{
    update();
}

void SpriteTextDecorator::draw(sf::RenderTarget &target, sf::RenderStates states) const
{
    target.draw(data->text, states);
}

void SpriteTextDecorator::update()
{
    auto sprite = getSprite();
    if (!sprite.expired()) {
        auto box = sprite.lock()->getBoundingBox();

        data->text.setRotation(getRotate());
        auto textBox = data->text.getGlobalBounds();
        auto position = Entity::adjustPosition(box, {textBox.width, textBox.height},getHAligment(),getVAlignment(), 0.0f, 0.0f);
        position.x -= box.left;
        position.y -= box.top;
        position.x -= textBox.left;
        position.y -= textBox.top;
        position += getOffset();
        data->text.setPosition(position);
    }
}

PTree SpriteTextDecorator::serialize()
{
    PTree node;
    node.add_child("textOption",data->option.serialize());
    auto text = data->text.getString();
    node.add("text",text.toAnsiString());
    node.add_child("textColor",serializeObject(data->text.getFillColor()));
    node.add("hAlignment",toString(getHAligment()));
    node.add("vAlignment",toString(getVAlignment()));
    node.add("rotate",getRotate());
    node.add_child("offset",serializeObject(getOffset()));
    return node;
}

void SpriteTextDecorator::deserialize(const PTree &node)
{
    data->option.deserialize(node.get_child("textOption"));
    TextOption::apply(data->text,data->option);
    data->text.setString(node.get_value("text"));
    data->text.setFillColor(deserializeColor(node.get_child("textColor")));
    setHAlignment(fromString(node.get_value("hAlignment"),HMode_Center));
    setVAlignment(fromString(node.get_value("vAlignment"),VMode_Center));
    setRotate(node.get<float>("rotate"));
    auto offset = deserializeVector2f(node.get_child("offset"));
    setXOffset(offset.x);
    setYOffset(offset.y);
}
